package com.mz.mattress.admin.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mz.mattress.admin.api.req.*;
import com.mz.mattress.admin.api.resp.*;
import com.mz.mattress.admin.mapper.*;
import com.mz.mattress.admin.service.CouponSendRecordService;
import com.mz.mattress.admin.service.DeviceService;
import com.mz.mattress.admin.service.MerchantService;
import com.mz.mattress.admin.util.ExcelUtil;
import com.mz.mattress.api.common.*;
import com.mz.mattress.api.entity.*;
import com.mz.mattress.api.enums.*;
import com.mz.mattress.api.jwt.JwtTokenUtil;
import com.mz.mattress.api.jwt.MerchantJwt;
import com.mz.mattress.api.redis.RedisKeys;
import com.mz.mattress.api.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.util.*;

@Service
@Slf4j
public class MerchantServiceImpl implements MerchantService {

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private MerchantDetailMapper merchantDetailMapper;

    @Autowired
    private MemberMerMapper memberMerMapper;

    @Autowired
    private MerchantCheckRecordMapper merchantCheckRecordMapper;

    @Autowired
    private SaleMapper saleMapper;

    @Autowired
    private OrderUseTimesBonusMapper orderUseTimesBonusMapper;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private InvestorMapper investorMapper;

    @Autowired
    private CouponSendRecordService couponSendRecordService;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Result<IPage<Merchant>> listPage(MerchantQueryReq req) {

        Page<Merchant> list = merchantMapper.listPage(req.newPage(), req.getProvince(), req.getCity(), req.getDistrict(),
                req.getName(), req.getSale(), req.getSaleId(), null, req.getInvestor(), req.getStatus(),
                req.getStatusType(), req.getGrade(), req.getDeviceCount(), req.getStartTime(), req.getEndTime());
        return Result.ok(list);

    }

    @Override
    public void exportList(HttpServletResponse response, MerchantQueryReq req) {

        List<Merchant> list = merchantMapper.listExport(req.getProvince(), req.getCity(), req.getDistrict(),
                req.getName(), req.getSale(), req.getSaleId(), null, req.getInvestor(), req.getStatus(),
                req.getStatusType(), req.getGrade(), req.getDeviceCount(), req.getStartTime(), req.getEndTime());

        ExcelUtil.simpleDownload(response, "商家", list);
    }

    @Override
    public Result<List<MerchantVo>> applyList(Long memberId) {
        List<MerchantVo> list = merchantMapper.selectApplyingByMemberId(memberId);
        return Result.ok(list);
    }

    @Override
    public Result<List<MerchantVo>> list(Long memberId) {
        List<MerchantVo> list = merchantMapper.selecOpeningtList(memberId);
        return Result.ok(list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result submit(MerchantApplyReq req) {

        Long memberId = req.getMemberId();
        String mobile = req.getMobile();
        Merchant merchant = req.getMerchant();
        if (memberId == null || merchant == null || mobile == null) {
            return Result.fail("参数错误");
        }

        Result valid = merchant.valid();
        if (valid.isFail()) {
            return valid;
        }

        if (merchant.getShop() != null) {
            String[] split = merchant.getShop().split(",");
            merchant.setImg(split[0]);
        }

        merchant.setSubmitTime(DateUtil.getNowDateTime());

        MemberMer memberMer = memberMerMapper.selectById(memberId);
        if (memberMer.getType() != Constants.ROLE_MERCHANT
                && memberMer.getTypeId() > 0) {
            //已是其他角色
            return Result.fail("不是商家");
        }

        //绑定服务商
        Result result = bindSale(merchant);
        if (result.isFail()) {
            return result;
        }

        //该会员 所有店铺
        Integer count = merchantMapper.selectCountByMemberId(memberId);
        Integer typeId = merchant.getId();

//        Merchant one = merchantMapper.selectApplyingByMemberId(memberId);
//        if (one != null) {
//            if (!one.getId().equals(id)) {
//                return Result.fail("已有店铺在申请中的");
//            }
//        }

        String token = null;
        if (typeId == null || typeId <= Constants.TYPE_ID_NOT_FIND) {
            merchant.setId(null);
            // 没有店铺，插入
            merchant.setMemberId(memberId);
            merchant.setStatus(MerchantStatusEnum.SUBMITTED.getValue());

            merchantMapper.insert(merchant);

            typeId = merchant.getId();

            MerchantDetail detail = merchant.getMerchantDetail();
            detail.setId(merchant.getId());
            merchantDetailMapper.insert(detail);

            if (count == 0) {

                //第一次申请 重新生成token
                MerchantJwt merchantJwt = new MerchantJwt();
                merchantJwt.setOpenId(memberMer.getOpenId());
                merchantJwt.setMemberMerId(memberMer.getId());
                merchantJwt.setSessionKey(memberMer.getSessionKey());
                merchantJwt.setMobile(memberMer.getMobile());
                merchantJwt.setType(memberMer.getType());
                merchantJwt.setTypeId(typeId);

                token = JwtTokenUtil.createMerchantToken(merchantJwt);
            }

        } else {

            merchant.setMemberId(memberId);
            merchant.setStatus(MerchantStatusEnum.SUBMITTED.getValue());
            merchantMapper.updateById(merchant);

            MerchantDetail detail = merchant.getMerchantDetail();
            detail.setId(merchant.getId());
            merchantDetailMapper.updateById(detail);
        }

        MemberMer update = new MemberMer();
        update.setId(memberId);
        update.setType(Constants.ROLE_MERCHANT);
        //提交了 下次登陆 默认这家门店
        update.setTypeId(typeId);
        //起初是单店
        update.setChainShop(count < 2 ? 0 : 1);
        memberMerMapper.updateById(update);

        return Result.ok(token);
    }

    //绑定服务商
    private Result bindSale(Merchant merchant) {

        Sale sale = null;
        if (merchant.getSaleId() != null) {
            sale = saleMapper.selectById(merchant.getSaleId());
        }
        if (sale == null && merchant.getSaleMobile() != null) {
            sale = saleMapper.selectByMobile(merchant.getSaleMobile());
        }

        if (sale == null) {
            return Result.fail("找不到服务商");
        }

        merchant.setSaleId(sale.getId());
        merchant.setTopSaleId(sale.getPid() == 0 ? sale.getId() : sale.getPid());
        merchant.setSaleMobile(sale.getMobile());
        merchant.setSaleName(sale.getName());

//        //当前销售员 门店数量+1
//        saleMapper.updateMerchantSubmit(merchant.getSaleId());
//
//        //父级销售员 门店数量+1
//        if (sale.getPid() > 0) {
//            saleMapper.updateMerchantSubmit(sale.getPid());
//        }

        return Result.ok();
    }

    @Override
    public Result<Merchant> getById(Integer id) {

        if (id <= 0) {
            Merchant merchant = new Merchant();
            merchant.setId(id);
            merchant.setStatus(MerchantStatusEnum.INIT.getValue());
            return Result.ok(merchant);
        }

        Merchant merchant = merchantMapper.selectById(id);
        if (merchant == null) {
            return Result.fail("商户不存在");
        }

        MerchantDetail detail = merchantDetailMapper.selectById(id);
        detail.filled(merchant);

        Result<DeviceSum> result = deviceService.deviceSum(id, null);
        if (result.isSuccess()) {
            DeviceSum sum = result.getResult();
            merchant.setDeviceTotal(sum.getDeviceTotal());
            merchant.setDeviceOff(sum.getDeviceOff());
        }

        return Result.ok(merchant);
    }

    @Override
    public Result updateById(MerchantApplyReq req) {

        Merchant merchant = req.getMerchant();

        if (merchant.getId() == null) {
            return Result.fail("没有ID");
        }

        //不能改
        merchant.setTopSaleId(null);
        merchant.setSaleId(null);
        merchant.setSaleMobile(null);
        merchant.setSaleName(null);
        merchant.setMobile(null);
        merchant.setStatus(null);
        if (ReflectUtil.hasValues(Merchant.class, merchant)) {
            merchantMapper.updateById(merchant);
        }

        MerchantDetail detail = merchant.getMerchantDetail();
        if (ReflectUtil.hasValues(MerchantDetail.class, detail)) {
            merchantDetailMapper.updateById(detail);
        }

        return Result.ok();
    }

    @Override
    public Result bindInvestor(MerchantInvestorBindReq req) {

        Set<Integer> ids = req.getIds();
        Integer investorId = req.getInvestorId();
        if (investorId == null) {

            //解绑
            for (Integer id : ids) {
                merchantMapper.cleanInvestor(id);
                merchantMapper.cleanDeviceInvestor(id);
            }

        } else {
            Investor investor = investorMapper.selectById(investorId);
            if (investor == null) {
                return Result.fail("找不到投资商");
            }

            if (investor.getMemberId() == null) {
                return Result.fail("投资商需用指定手机号登陆小程序，绑定会员信息");
            }

            for (Integer id : ids) {
                Merchant update = new Merchant();
                update.setId(id);
                update.setInvestorId(investor.getId());
                update.setInvestorName(investor.getName());
                update.setInvestorMobile(investor.getMobile());
                merchantMapper.updateById(update);
            }

            merchantMapper.bindDeviceInvestor();
        }

        return Result.ok();
    }

    @Override
    public Result updateCard(Integer id, Integer card) {

        if (card == null || id == null) {
            return Result.fail();
        }

        Merchant update = new Merchant();
        update.setId(id);
        update.setCard(card);
        merchantMapper.updateById(update);

        return Result.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result check(MerchantCheckReq checkReq, Integer userId, String userName) {

        Integer id = checkReq.getMerchantId();
        Integer action = checkReq.getAction();
        String reason = checkReq.getReason();

        Merchant merchant = merchantMapper.selectById(id);
        if (merchant == null) {
            return Result.fail("找不到商家");
        }

        MerchantStatusEnum newStatus = null;
        MerchantStatusEnum curStatus = MerchantStatusEnum.valueOf(merchant.getStatus());

        if (curStatus == MerchantStatusEnum.SUBMITTED) {
            if (action.equals(Constants.CHECK_PASS)) {
                newStatus = MerchantStatusEnum.CHECK_PASS;
            } else {
                newStatus = MerchantStatusEnum.CHECK_FAIL;
            }
        }

        if (newStatus == null) {
            return Result.fail("状态不对");
        }

        Merchant update = new Merchant();
        update.setId(id);
        update.setStatus(newStatus.getValue());
        update.setReason(reason);
        update.setCheckTime(DateUtil.getNowDateTime());

        //审核通过，填入驻时间
        if (newStatus == MerchantStatusEnum.CHECK_PASS) {
            update.setEnterTime(update.getCheckTime());
            update.setReason("");
        }

        merchantMapper.updateById(update);

        MerchantCheckRecord record = new MerchantCheckRecord();
        record.setMerchantId(id);
        record.setUserId(userId);
        record.setUserName(userName);
        record.setAction(action);
        record.setRemark(reason);
        merchantCheckRecordMapper.insert(record);

//        //更新销售员 门店数量
//        if (merchant.getSaleId() != null) {
//
//            if (newStatus == MerchantStatusEnum.CHECK_PASS) {
//
//                //当前销售员 门店数量+1
//                saleMapper.updateMerchantCheckPass(merchant.getSaleId());
//
//                if (merchant.getTopSaleId() != null &&
//                        !Objects.equals(merchant.getSaleId(), merchant.getTopSaleId())) {
//                    saleMapper.updateMerchantCheckPass(merchant.getTopSaleId());
//                }
//
//            } else {
//
//                //审核失败
//                //当前销售员 门店数量-1
//                saleMapper.updateMerchantCheckFail(merchant.getSaleId());
//
//                if (merchant.getTopSaleId() != null &&
//                        !Objects.equals(merchant.getSaleId(), merchant.getTopSaleId())) {
//                    saleMapper.updateMerchantCheckFail(merchant.getTopSaleId());
//                }
//            }
//
//        }

        //商家审核通过发放优惠券
        couponSendRecordService.addBySendType(merchant.getMobile(), CouponSendTypeEnum.MERCHANT_CHECK_PASS);

        return Result.ok();
    }

    @Override
    public Result<List<MerchantCheckRecord>> records(Integer id) {
        List<MerchantCheckRecord> list = merchantCheckRecordMapper.selectByMerchantId(id);
        return Result.ok(list);
    }


//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public Result add(MerchantAddReq addReq, Integer headId, String mobile) {
//
//        Merchant merchant = MerchantConverter.INSTANCE.toMerchant(addReq);
//        validateParam(merchant);
//
//        //  设置总店信息
//        merchant.setPid(headId);
//        Merchant headMerchant = merchantMapper.selectById(headId);
//        merchant.setSaleId(merchant.getId());
//        merchant.setFromMobile(headMerchant.getFromMobile());
//
//        doAdd(merchant);
//
//        redisClient.setAdd(RedisKeys.CHANGE_TOKEN_ACCOUNT, mobile);
//
//        return Result.ok();
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public Result updateById(@Valid MerchantUpdateReq updateReq) {
//
//        Merchant merchant = MerchantConverter.INSTANCE.toMerchant(updateReq);
//
//        validateParam(merchant);
//
//        Merchant srcMerchant = merchantMapper.selectById(updateReq.getId());

    /// /        if (srcMerchant.getStatus() != MerchantStatusEnum.CheckFail.getValue()) {
    /// /            throw new ServiceException("仅审核失败店铺可重新编辑");
    /// /        }
//        merchant.setStatus(MerchantStatusEnum.WaitCheck.getValue());
//
//        merchantMapper.updateById(merchant);
//
//        MerchantDetail merchantDetail = MerchantConverter.INSTANCE.toMerchantDetail(updateReq);
//        merchantDetailMapper.updateById(merchantDetail);
//
//        return Result.ok();
//    }
    @Override
    public Result updateInfoById(Merchant merchant) {

        Integer id = merchant.getId();
        if (id == null) {
            return Result.fail("id=null");
        }

        Merchant update = new Merchant();
        update.setId(merchant.getId());

        //更改手机号
        String mobile = merchant.getMobile();
        if (mobile != null) {

            if (!RegexUtil.isMobileExact(mobile)) {
                return Result.fail("手机号错误");
            }

//            Integer merchantId = merchantMapper.selectByMobile(mobile);
//            if (merchantId != null) {
//                return Result.fail("该手机号已存在商家中");
//            }
//
//            String obj = memberMapper.selectIdByMobile(mobile);
//            if (obj != null) {
//                return Result.fail("该手机号已存在会员中");
//            }
//
//            update.setMobile(mobile);
//            merchantMapper.updateById(update);
//
//            // 更改商家对应的会员手机号
//            memberMapper.updateMobileByTypeId(mobile, MemberTypeEnum.MERCHANT.getValue(), id);
//
//            Map<String, String> params = new HashMap<>();
//            Result result = newSmsUtil.send(mobile, SmsEnum.CHANGE_MERCHANT_MOBILE, params);
//            if (result.isFail()) {
//                log.warn("send_sms_notify_fail, type:{}, result:{}", SmsEnum.CHANGE_MERCHANT_MOBILE, result.getMessage());
//            }
            return Result.ok();
        }

        return Result.fail();
    }

    @Override
    public Result deleteById(Integer id) {

        Merchant merchant = merchantMapper.selectById(id);
        if (merchant == null) {
            return Result.fail("找不到商家");
        }
        if (merchant.getStatus() != MerchantStatusEnum.CHECK_FAIL.getValue() &&
                merchant.getStatus() != MerchantStatusEnum.DISABLE.getValue()) {
            return Result.fail("商家状态不对");
        }

        //清空商家绑定的数据
        merchantMapper.deletedMerchant(id);

        return Result.ok();
    }

//    @Override
//    public Result deleteByIds(Set<Integer> ids) {
//        merchantMapper.deleteBatchIds(ids);
//        return Result.ok();
//    }

    @Override
    public Result<MerchantSum> headSum(Integer typeId, Long memberMerId, String dates) {

        //类型 0平台 1商家 2销售 3子销售
        Integer type = 1;

        if (memberMerId == null || typeId == null) {
            return Result.fail("参数错误");
        }

        MerchantSum sum = new MerchantSum();

        //总收益 消费次数 成交客户

        Integer memberCount = null;
        BonusSum bonusSum = null;
        if (typeId.equals(Constants.TYPE_ID_ALL)) {
            memberCount = orderUseTimesBonusMapper.selectMemberCount(null, null, memberMerId, null);
            bonusSum = orderUseTimesBonusMapper.selectBonusSum(null, null, memberMerId, null);
        } else {
            memberCount = orderUseTimesBonusMapper.selectMemberCount(type, typeId, null, null);
            bonusSum = orderUseTimesBonusMapper.selectBonusSum(type, typeId, null, null);
        }

        sum.setMemberCount(memberCount);
        sum.setTotalBonus(bonusSum.getBonus() == null ? 0 : bonusSum.getBonus());
        sum.setRecordCount(bonusSum.getCount());

        sum.setDeviceTotal(0);
        sum.setDeviceOff(0);
        sum.setDeviceOn(0);
        return Result.ok(sum);
    }

    @Override
    public Result<MerchantSum> merchantSum(Integer typeId, Long memberMerId, Integer days) {

        //类型 0平台 1商家 2销售 3子销售
        Integer type = 1;

        if (memberMerId == null || typeId == null) {
            return Result.fail("参数错误");
        }

        MerchantSum sum = new MerchantSum();

        //总收益 消费次数 成交客户

        Integer memberCount = null;
        BonusSum bonusSum = null;

        days = days == null ? 0 : -days;
        String startTime = DateUtil.getNowDayPlus(days);

        if (typeId.equals(Constants.TYPE_ID_ALL)) {
            memberCount = orderUseTimesBonusMapper.selectMemberCount(null, null, memberMerId, startTime);
            bonusSum = orderUseTimesBonusMapper.selectBonusSum(null, null, memberMerId, startTime);
        } else {
            memberCount = orderUseTimesBonusMapper.selectMemberCount(type, typeId, null, startTime);
            bonusSum = orderUseTimesBonusMapper.selectBonusSum(type, typeId, null, startTime);
        }

        sum.setMemberCount(memberCount);
        sum.setTotalBonus(bonusSum.getBonus() == null ? 0 : bonusSum.getBonus());
        sum.setRecordCount(bonusSum.getCount());

        Integer count = merchantMapper.selectApplyingCountByMemberId(memberMerId);
        sum.setApplyMerchant(count);

        Result<DeviceSum> result = deviceService.deviceSum(typeId, memberMerId);
        if (result.isSuccess()) {
            DeviceSum deviceSum = result.getResult();
            sum.setDeviceTotal(deviceSum.getDeviceTotal());
            sum.setDeviceOff(deviceSum.getDeviceOff());
            sum.setDeviceOn(deviceSum.getDeviceOn());
        } else {
            sum.setDeviceTotal(0);
            sum.setDeviceOff(0);
            sum.setDeviceOn(0);
        }

        return Result.ok(sum);
    }

    @Override
    public void bindSaleUpdate() {


        List<Merchant> list = merchantMapper.list2();

        for (Merchant merchant : list) {

            if (merchant.getSaleMobile().length() > 0) {

                Sale sale = saleMapper.selectByMobile(merchant.getSaleMobile());

                if (sale == null) {
                    continue;
                }

                Merchant update = new Merchant();
                update.setId(merchant.getId());
                update.setSaleId(sale.getId());
                update.setTopSaleId(sale.getPid() == 0 ? sale.getId() : sale.getPid());
                update.setSaleMobile(sale.getMobile());
                update.setSaleName(sale.getName());
                merchantMapper.updateById(update);

            }

        }

    }

    @Override
    public Result bindSaleByMobile(Integer id, String saleMobile) {

        Sale sale = saleMapper.selectByMobile(saleMobile);
        if (sale == null) {
            return Result.fail("找不到服务商");
        }

        Merchant update = new Merchant();
        update.setId(id);
        update.setSaleId(sale.getId());
        update.setTopSaleId(sale.getPid() == 0 ? sale.getId() : sale.getPid());
        update.setSaleMobile(sale.getMobile());
        update.setSaleName(sale.getName());
        merchantMapper.updateById(update);

        return Result.ok(sale);
    }

    @Override
    public Result downUpMerchant(MerchantDownUpReq req, Integer userId, String userName) {

        Integer merchantId = req.getMerchantId();
        Integer action = req.getAction();

        Merchant merchant = merchantMapper.selectById(merchantId);
        if (merchant == null) {
            return Result.fail("找不到商家");
        }

        //动作 1down 2up
        if (action == 1) {
            Integer count = deviceMapper.selectCountByMerchantId(merchantId);
            if (count > 0) {
                return Result.fail("请先解绑设备");
            }
//            List<Device> devices = deviceMapper.selectByMerchantId(merchantId);
//            if (devices.size() > 0) {
//                return Result.fail("请先解绑设备");
//            }
        }

        Merchant update = new Merchant();
        update.setId(merchantId);
        update.setStatus(action == 1 ? MerchantStatusEnum.DISABLE.getValue() : MerchantStatusEnum.CHECK_PASS.getValue());
        merchantMapper.updateById(update);

        String merchantKey = RedisKeys.getLockMerchantKey(merchant.getId());
        if (action == 1) {
            //冻结用户
            redisTemplate.opsForValue().set(merchantKey, "1");
        } else {
            //解除冻结
            redisTemplate.delete(merchantKey);
        }

        MerchantCheckRecord record = new MerchantCheckRecord();
        record.setMerchantId(merchantId);
        record.setUserId(userId);
        record.setUserName(userName);
        record.setRemark(action == 1 ? "禁用" : "审核通过");
        merchantCheckRecordMapper.insert(record);

        return Result.ok();
    }

    @Override
    public Result sumDevice() {

        merchantMapper.cleanDeviceCount();

        List<MerchantDeviceSum> list = deviceMapper.sumDevice();

        for (MerchantDeviceSum sum : list) {
            if (sum.getMerchantId() == null) {
                continue;
            }

            Merchant update = new Merchant();
            update.setId(sum.getMerchantId());
            update.setDeviceCount(sum.getCount());
            merchantMapper.updateById(update);
        }

        return Result.ok();
    }

    @Override
    public Result resetCanUse(Integer merchantId) {
        deviceMapper.resetCanUseByMerchantId(merchantId);
        return Result.ok();
    }

    public static void main(String[] args) {

        LocalDate now = LocalDate.now();

        System.out.println(DateUtil.getNowDayPlus(-1));
        System.out.println(DateUtil.getNowDayPlus(-7));
        System.out.println(DateUtil.getNowDayPlus(0));

    }

}
